/
Util.go
171 lines (146 loc) · 5.18 KB
/
Util.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
* Copyright (c) 2020 Devtron Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package git
import (
"fmt"
"github.com/devtron-labs/git-sensor/internals/middleware"
"github.com/devtron-labs/git-sensor/internals/sql"
"io/ioutil"
"os"
"path"
"strconv"
"strings"
)
const (
GIT_BASE_DIR = "/git-base/"
SSH_PRIVATE_KEY_DIR = GIT_BASE_DIR + "ssh-keys/"
SSH_PRIVATE_KEY_FILE_NAME = "ssh_pvt_key"
CLONE_TIMEOUT_SEC = 600
FETCH_TIMEOUT_SEC = 30
GITHUB_PROVIDER = "github.com"
GITLAB_PROVIDER = "gitlab.com"
CloningModeShallow = "SHALLOW"
CloningModeFull = "FULL"
)
//git@gitlab.com:devtron-client-gitops/wms-user-management.git
//https://gitlab.com/devtron-client-gitops/wms-user-management.git
//git@bitbucket.org:DelhiveryTech/kafka-consumer-config.git
//https://prashant-delhivery@bitbucket.org/DelhiveryTech/kafka-consumer-config.git
func GetProjectName(url string) string {
//if url = https://github.com/devtron-labs/git-sensor.git then it will return git-sensor
url = url[strings.LastIndex(url, "/")+1:]
return strings.TrimSuffix(url, ".git")
}
func GetCheckoutPath(url string, cloneLocation string) string {
//url= https://github.com/devtron-labs/git-sensor.git cloneLocation= git-base/1/github.com/prakash100198
//then this function returns git-base/1/github.com/prakash100198/SampleGoLangProject/.git
projectName := GetProjectName(url)
projRootDir := cloneLocation + "/" + projectName + "/.git"
return projRootDir
}
func GetUserNamePassword(gitProvider *sql.GitProvider) (userName, password string, err error) {
switch gitProvider.AuthMode {
case sql.AUTH_MODE_USERNAME_PASSWORD:
return gitProvider.UserName, gitProvider.Password, nil
case sql.AUTH_MODE_ACCESS_TOKEN:
return gitProvider.UserName, gitProvider.AccessToken, nil
case sql.AUTH_MODE_ANONYMOUS:
return "", "", nil
case sql.AUTH_MODE_SSH:
return "", "", nil
default:
return "", "", fmt.Errorf("unsupported %s", gitProvider.AuthMode)
}
}
func GetOrCreateSshPrivateKeyOnDisk(gitProviderId int, sshPrivateKeyContent string) (privateKeyPath string, err error) {
sshPrivateKeyFolderPath := path.Join(SSH_PRIVATE_KEY_DIR, strconv.Itoa(gitProviderId))
sshPrivateKeyFilePath := path.Join(sshPrivateKeyFolderPath, SSH_PRIVATE_KEY_FILE_NAME)
// if file exists then return
if _, err := os.Stat(sshPrivateKeyFilePath); os.IsExist(err) {
return sshPrivateKeyFilePath, nil
}
// create dirs
err = os.MkdirAll(sshPrivateKeyFolderPath, 0755)
if err != nil {
return "", err
}
// create file with content
err = ioutil.WriteFile(sshPrivateKeyFilePath, []byte(sshPrivateKeyContent), 0600)
if err != nil {
return "", err
}
return sshPrivateKeyFilePath, nil
}
func CreateOrUpdateSshPrivateKeyOnDisk(gitProviderId int, sshPrivateKeyContent string) error {
sshPrivateKeyFolderPath := path.Join(SSH_PRIVATE_KEY_DIR, strconv.Itoa(gitProviderId))
sshPrivateKeyFilePath := path.Join(sshPrivateKeyFolderPath, SSH_PRIVATE_KEY_FILE_NAME)
// if file exists then delete file
if _, err := os.Stat(sshPrivateKeyFilePath); os.IsExist(err) {
os.Remove(sshPrivateKeyFilePath)
}
// create dirs
err := os.MkdirAll(sshPrivateKeyFolderPath, 0755)
if err != nil {
return err
}
// create file with content
err = ioutil.WriteFile(sshPrivateKeyFilePath, []byte(sshPrivateKeyContent), 0600)
if err != nil {
return err
}
return nil
}
// sample commitDiff :=4\t3\tModels/models.go\n2\t2\tRepository/Repository.go\n0\t2\main.go
func getFileStat(commitDiff string) (FileStats, error) {
filestat := FileStats{}
lines := strings.Split(strings.TrimSpace(commitDiff), "\n")
for _, line := range lines {
parts := strings.Split(line, "\t")
if len(parts) != 3 {
fmt.Printf("invalid git diff --numstat output, parts: %v\n", parts)
middleware.CommitStatParsingErrorCounter.WithLabelValues().Inc()
continue
}
if parts[0] == "-" && parts[1] == "-" {
// ignoring binary file
continue
}
var isParsingError bool
//TODO not ignoring in case of error in below cases because of include/exclude feature where file name is important
added, err := strconv.Atoi(parts[0])
if err != nil {
fmt.Printf("failed to parse number of lines added: %v\n", err)
isParsingError = true
}
deleted, err := strconv.Atoi(parts[1])
if err != nil {
fmt.Printf("failed to parse number of lines deleted: %v\n", err)
isParsingError = true
}
if isParsingError {
middleware.CommitStatParsingErrorCounter.WithLabelValues().Inc()
}
filestat = append(filestat, FileStat{
Name: parts[2],
Addition: added,
Deletion: deleted,
})
}
return filestat, nil
}
func IsRepoShallowCloned(checkoutPath string) bool {
return strings.Contains(checkoutPath, "/.git")
}