/
git.go
149 lines (125 loc) · 3.99 KB
/
git.go
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
* Copyright 2019 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package config
import (
"fmt"
"net/url"
"path"
"strings"
"github.com/newrelic/nri-flex/internal/load"
"github.com/sirupsen/logrus"
"github.com/spf13/afero"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
)
var appFS = afero.NewOsFs()
// SyncGitConfigs Clone git repo if already exists, else pull latest version
func SyncGitConfigs(customDir string) (bool, error) {
if load.Args.GitToken == "" ||
load.Args.GitUser == "" ||
load.Args.GitRepo == "" {
load.Logrus.Debug("config: git sync configuration not set")
return false, nil
}
syncDir := load.Args.ConfigDir
if customDir != "" {
syncDir = customDir
}
if !strings.HasSuffix(load.Args.GitRepo, "/") {
load.Args.GitRepo = load.Args.GitRepo + "/"
}
load.Logrus.Debugf("config: syncing git configs %v %v into %v", load.Args.GitService, load.Args.GitRepo, syncDir)
u, err := url.Parse(load.Args.GitRepo)
if err != nil {
return false, fmt.Errorf("config: git sync invalid url, repo: %s, error: %v ", load.Args.GitRepo, err)
}
repoDir := path.Join(syncDir, u.Path)
_, err = appFS.Stat(repoDir)
// If cannot access the repo dir, clone it.
if err != nil {
load.Logrus.WithFields(logrus.Fields{
"repo": load.Args.GitRepo,
}).Debug("config: git sync cloning repo")
err = GitClone(repoDir, u)
if err != nil {
return false, fmt.Errorf("config: git clone failed, repo: %s, error: %v ", load.Args.GitRepo, err)
}
} else {
load.Logrus.WithFields(logrus.Fields{
"repo": load.Args.GitRepo,
}).Debug("config: git sync pulling repo")
err = GitPull(repoDir)
if err != nil {
return false, fmt.Errorf("config: git sync pull failed, repo: %s, error: %v ", load.Args.GitRepo, err)
}
}
return true, nil
}
// GitClone git clone
func GitClone(dir string, u *url.URL) error {
r, err := git.PlainClone(dir, false, &git.CloneOptions{
URL: u.Scheme + "://" + load.Args.GitUser + ":" + load.Args.GitToken + "@" + u.Host + u.Path,
// Progress: os.Stdout,
})
if err != nil {
return fmt.Errorf("failed to clone repo, error: %v", err)
}
// Get the working directory for the repository
w, err := r.Worktree()
if err != nil {
return fmt.Errorf("failed to get working directory while cloning the repo, error: %v", err)
}
err = GitCheckout(w)
if err != nil {
return fmt.Errorf("failed to clone repo, error: %v", err)
}
return nil
}
// GitPull git pull
func GitPull(dir string) error {
// instantiate a new repository targeting the given path (the .git folder)
r, err := git.PlainOpen(dir)
if err != nil {
return fmt.Errorf("failed to pull from repo, error: %v", err)
}
// Get the working directory for the repository
w, err := r.Worktree()
if err != nil {
return fmt.Errorf("failed to get working directory while pulling the repo, error: %v", err)
}
err = GitCheckout(w)
if err != nil {
return fmt.Errorf("failed to pull from repo, error: %v", err)
}
// Pull the latest changes from the origin remote and merge into the current branch
err = w.Pull(&git.PullOptions{RemoteName: "origin"})
if err != nil {
if err.Error() == "already up-to-date" {
load.Logrus.Debug("config: git pull - " + dir + " " + err.Error())
return nil
}
return fmt.Errorf("error occurred while pulling the repo, error: %v", err)
}
return nil
}
// GitCheckout git checkout
func GitCheckout(w *git.Worktree) error {
if load.Args.GitBranch != "" && load.Args.GitCommit == "" {
err := w.Checkout(&git.CheckoutOptions{
Branch: plumbing.NewBranchReferenceName(load.Args.GitBranch),
})
if err != nil {
return fmt.Errorf("failed to checkout repo: %s, branch: %s, error: %v", load.Args.GitRepo, load.Args.GitBranch, err)
}
} else if load.Args.GitCommit != "" {
err := w.Checkout(&git.CheckoutOptions{
Hash: plumbing.NewHash(load.Args.GitCommit),
})
if err != nil {
return fmt.Errorf("failed to checkout repo: %s, commit: %s, error: %v", load.Args.GitRepo, load.Args.GitCommit, err)
}
}
return nil
}