diff options
Diffstat (limited to 'cmd/generate/gitcache.go')
-rw-r--r-- | cmd/generate/gitcache.go | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/cmd/generate/gitcache.go b/cmd/generate/gitcache.go new file mode 100644 index 0000000..7caf024 --- /dev/null +++ b/cmd/generate/gitcache.go @@ -0,0 +1,66 @@ +package main + +import ( + "fmt" + "os" + "os/exec" + "strings" + + "git.mothstuff.lol/lukeshu/eclipse/lib/gitcache" +) + +var gitFetched = map[string]struct{}{} + +var gitCache = &gitcache.Cache{ + Dir: ".git-cache", +} + +func withGit(u string, fn func(dir string) error) error { + if _, ok := gitFetched[u]; !ok { + if err := gitCache.Fetch(os.Stderr, u); err != nil { + return err + } + } + return gitCache.WithFastClone(os.Stderr, u, fn) +} + +func getGitTagThatContainsAll(gitURL string, gitHashes ...string) (string, error) { + if len(gitHashes) == 0 { + return "", nil + } + var tag string + err := withGit(gitURL, func(dir string) error { + gitHash := gitHashes[0] + if len(gitHashes) > 1 { + cmdline := append([]string{"git", "merge-base", "--independent", "--"}, gitHashes...) + cmd := exec.Command(cmdline[0], cmdline[1:]...) + cmd.Dir = dir + var stdout strings.Builder + cmd.Stdout = &stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return err + } + gitHash = strings.TrimSpace(stdout.String()) + } + cmd := exec.Command("git", "for-each-ref", + "--count=1", + "--format=%(refname:lstrip=2)", + "--contains="+gitHash, + "refs/tags/", + ) + cmd.Dir = dir + var stdout strings.Builder + cmd.Stdout = &stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return err + } + tag = strings.TrimSpace(stdout.String()) + return nil + }) + if err != nil { + return "", fmt.Errorf("%q: %w", gitURL, err) + } + return tag, nil +} |