forked from sourcegraph/src-cli
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgitutil.go
More file actions
74 lines (61 loc) · 1.96 KB
/
gitutil.go
File metadata and controls
74 lines (61 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package codeintel
import (
"fmt"
"net/url"
"os/exec"
"path/filepath"
"strings"
)
// InferRepo gets a Sourcegraph-friendly repo name from the git clone enclosing the working dir.
func InferRepo() (string, error) {
remoteURL, err := runGitCommand("remote", "get-url", "origin")
if err != nil {
return "", err
}
return parseRemote(remoteURL)
}
// parseRemote converts a git origin url into a Sourcegraph-friendly repo name.
func parseRemote(remoteURL string) (string, error) {
// e.g., git@github.com:sourcegraph/src-cli.git
if strings.HasPrefix(remoteURL, "git@") {
if parts := strings.Split(remoteURL, ":"); len(parts) == 2 {
return strings.Join([]string{
strings.TrimPrefix(parts[0], "git@"),
strings.TrimSuffix(parts[1], ".git"),
}, "/"), nil
}
}
// e.g., https://github.com/sourcegraph/src-cli.git
if url, err := url.Parse(remoteURL); err == nil {
return url.Hostname() + strings.TrimSuffix(url.Path, ".git"), nil
}
return "", fmt.Errorf("unrecognized remote URL: %s", remoteURL)
}
// InferCommit gets a 40-character rev hash from the git clone enclosing the working dir.
func InferCommit() (string, error) {
return runGitCommand("rev-parse", "HEAD")
}
// InferRoot gets the path relative to the root of the git clone enclosing the given file path.
func InferRoot(file string) (string, error) {
topLevel, err := runGitCommand("rev-parse", "--show-toplevel")
if err != nil {
return "", err
}
absoluteFile, err := filepath.Abs(file)
if err != nil {
return "", err
}
relative, err := filepath.Rel(topLevel, absoluteFile)
if err != nil {
return "", err
}
return filepath.Dir(relative), nil
}
// runGitCommand runs a git command and trims all leading/trailing whitespace from the output.
func runGitCommand(args ...string) (string, error) {
output, err := exec.Command("git", args...).CombinedOutput()
if err != nil {
return "", fmt.Errorf("failed to run git command: %s\n%s", err, output)
}
return strings.TrimSpace(string(output)), nil
}