git-module

git clone git://git.lin.moe/fork/git-module.git

 1package git
 2
 3import (
 4	"context"
 5	"fmt"
 6	"io"
 7	"strings"
 8	"sync"
 9)
10
11var (
12	// logOutput is the writer to write logs. When not set, no log will be produced.
13	logOutput io.Writer
14	// logPrefix is the prefix prepend to each log entry.
15	logPrefix = "[git-module] "
16)
17
18// SetOutput sets the output writer for logs.
19func SetOutput(output io.Writer) {
20	logOutput = output
21}
22
23// SetPrefix sets the prefix to be prepended to each log entry.
24func SetPrefix(prefix string) {
25	logPrefix = prefix
26}
27
28func logf(format string, args ...interface{}) {
29	if logOutput == nil {
30		return
31	}
32
33	_, _ = fmt.Fprint(logOutput, logPrefix)
34	_, _ = fmt.Fprintf(logOutput, format, args...)
35	_, _ = fmt.Fprintln(logOutput)
36}
37
38var (
39	// gitVersion stores the Git binary version.
40	// NOTE: To check Git version should call BinVersion not this global variable.
41	gitVersion    string
42	gitVersionMu  sync.Mutex
43	gitVersionSet bool
44)
45
46// BinVersion returns current Git binary version that is used by this module.
47// Successful results are cached; failed attempts are not cached, allowing
48// retries with a fresh context.
49func BinVersion(ctx context.Context) (string, error) {
50	gitVersionMu.Lock()
51	defer gitVersionMu.Unlock()
52
53	if gitVersionSet {
54		return gitVersion, nil
55	}
56
57	stdout, err := exec(ctx, "", []string{"version"}, nil)
58	if err != nil {
59		return "", err
60	}
61
62	fields := strings.Fields(string(stdout))
63	if len(fields) < 3 {
64		return "", fmt.Errorf("not enough output: %s", stdout)
65	}
66
67	// Handle special case on Windows.
68	i := strings.Index(fields[2], "windows")
69	if i >= 1 {
70		gitVersion = fields[2][:i-1]
71	} else {
72		gitVersion = fields[2]
73	}
74
75	gitVersionSet = true
76	return gitVersion, nil
77}