in gitindex/index.go [345:493]
func IndexGitRepo(opts Options) error {
// Set max thresholds, since we use them in this function.
opts.BuildOptions.SetDefaults()
if opts.RepoDir == "" {
return fmt.Errorf("gitindex: must set RepoDir")
}
opts.BuildOptions.RepositoryDescription.Source = opts.RepoDir
repo, err := git.PlainOpen(opts.RepoDir)
if err != nil {
return err
}
if err := setTemplatesFromConfig(&opts.BuildOptions.RepositoryDescription, opts.RepoDir); err != nil {
log.Printf("setTemplatesFromConfig(%s): %s", opts.RepoDir, err)
}
repoCache := NewRepoCache(opts.RepoCacheDir)
// branch => (path, sha1) => repo.
repos := map[fileKey]BlobLocation{}
// fileKey => branches
branchMap := map[fileKey][]string{}
// Branch => Repo => SHA1
branchVersions := map[string]map[string]plumbing.Hash{}
branches, err := expandBranches(repo, opts.Branches, opts.BranchPrefix)
if err != nil {
return err
}
for _, b := range branches {
commit, err := getCommit(repo, opts.BranchPrefix, b)
if err != nil {
if opts.AllowMissingBranch && err.Error() == "reference not found" {
continue
}
return err
}
opts.BuildOptions.RepositoryDescription.Branches = append(opts.BuildOptions.RepositoryDescription.Branches, zoekt.RepositoryBranch{
Name: b,
Version: commit.Hash.String(),
})
tree, err := commit.Tree()
if err != nil {
return err
}
files, subVersions, err := TreeToFiles(repo, tree, opts.BuildOptions.RepositoryDescription.URL, repoCache)
if err != nil {
return err
}
for k, v := range files {
repos[k] = v
branchMap[k] = append(branchMap[k], b)
}
branchVersions[b] = subVersions
}
if opts.Incremental && opts.BuildOptions.IncrementalSkipIndexing() {
return nil
}
reposByPath := map[string]BlobLocation{}
for key, location := range repos {
reposByPath[key.SubRepoPath] = location
}
opts.BuildOptions.SubRepositories = map[string]*zoekt.Repository{}
for path, location := range reposByPath {
tpl := opts.BuildOptions.RepositoryDescription
if path != "" {
tpl = zoekt.Repository{URL: location.URL.String()}
if err := SetTemplatesFromOrigin(&tpl, location.URL); err != nil {
log.Printf("setTemplatesFromOrigin(%s, %s): %s", path, location.URL, err)
}
}
opts.BuildOptions.SubRepositories[path] = &tpl
}
for _, br := range opts.BuildOptions.RepositoryDescription.Branches {
for path, repo := range opts.BuildOptions.SubRepositories {
id := branchVersions[br.Name][path]
repo.Branches = append(repo.Branches, zoekt.RepositoryBranch{
Name: br.Name,
Version: id.String(),
})
}
}
builder, err := build.NewBuilder(opts.BuildOptions)
if err != nil {
return err
}
defer builder.Finish()
var names []string
fileKeys := map[string][]fileKey{}
for key := range repos {
n := key.FullPath()
fileKeys[n] = append(fileKeys[n], key)
names = append(names, n)
}
sort.Strings(names)
names = uniq(names)
for _, name := range names {
keys := fileKeys[name]
for _, key := range keys {
brs := branchMap[key]
blob, err := repos[key].Repo.BlobObject(key.ID)
if err != nil {
return err
}
if blob.Size > int64(opts.BuildOptions.SizeMax) && !opts.BuildOptions.IgnoreSizeMax(key.FullPath()) {
if err := builder.Add(zoekt.Document{
SkipReason: fmt.Sprintf("file size %d exceeds maximum size %d", blob.Size, opts.BuildOptions.SizeMax),
Name: key.FullPath(),
Branches: brs,
SubRepositoryPath: key.SubRepoPath,
}); err != nil {
return err
}
continue
}
contents, err := blobContents(blob)
if err != nil {
return err
}
if err := builder.Add(zoekt.Document{
SubRepositoryPath: key.SubRepoPath,
Name: key.FullPath(),
Content: contents,
Branches: brs,
}); err != nil {
return err
}
}
}
return builder.Finish()
}