-
Notifications
You must be signed in to change notification settings - Fork 94
Expand file tree
/
Copy pathutils.go
More file actions
192 lines (177 loc) · 7.63 KB
/
utils.go
File metadata and controls
192 lines (177 loc) · 7.63 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
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
package dependencies
import (
"errors"
"fmt"
"net/http"
"os"
"path"
biutils "github.com/jfrog/build-info-go/utils"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-client-go/http/httpclient"
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"github.com/jfrog/jfrog-client-go/utils/io/httputils"
"github.com/jfrog/jfrog-client-go/utils/log"
)
const (
ChecksumFileName = "checksum.sha2"
jarsDocumentation = "https://docs.jfrog.com/artifactory/docs/jf-mvn#downloading-the-maven-and-gradle-extractor-jars"
)
// Download the relevant build-info-extractor jar.
// By default, the jar is downloaded directly from jfrog releases.
//
// targetPath: The local download path (without the file name).
// downloadPath: Artifactory download path.
func DownloadExtractor(targetPath, downloadPath string) error {
artDetails, remotePath, err := GetExtractorsRemoteDetails(downloadPath)
if err != nil {
return err
}
return DownloadDependency(artDetails, remotePath, targetPath, false)
}
func CreateChecksumFile(targetPath, checksum string) (err error) {
out, err := os.Create(targetPath)
defer func() {
err = errors.Join(err, errorutils.CheckError(out.Close()))
}()
if errorutils.CheckError(err) != nil {
return err
}
if _, err = out.Write([]byte(checksum)); err != nil {
return errorutils.CheckError(err)
}
return
}
// GetExtractorsRemoteDetails retrieves the server details necessary to download the build-info extractors from a remote repository.
// downloadPath - specifies the path in the remote repository from which the extractors will be downloaded.
func GetExtractorsRemoteDetails(downloadPath string) (server *config.ServerDetails, remoteRepo string, err error) {
// Download from the remote repository that proxies https://releases.jfrog.io
server, remoteRepo, err = getExtractorsRemoteDetailsFromEnv(downloadPath)
if remoteRepo == "" && err == nil {
// Fallback to the deprecated JFROG_CLI_EXTRACTORS_REMOTE environment variable
server, remoteRepo, err = getExtractorsRemoteDetailsFromLegacyEnv(downloadPath)
}
if remoteRepo != "" || err != nil {
return
}
// Download directly from https://releases.jfrog.io
log.Info("The build-info-extractor jar is not cached locally. Downloading it now...\n" +
"You can set the repository from which this jar is downloaded.\n" +
"Read more about it at " + jarsDocumentation)
log.Debug("'" + coreutils.ReleasesRemoteEnv + "' environment variable is not configured. Downloading directly from releases.jfrog.io.")
// If not configured to download through a remote repository in Artifactory, download from releases.jfrog.io.
return &config.ServerDetails{ArtifactoryUrl: coreutils.JfrogReleasesUrl}, path.Join("oss-release-local", downloadPath), nil
}
func getExtractorsRemoteDetailsFromEnv(downloadPath string) (server *config.ServerDetails, remoteRepo string, err error) {
server, remoteRepo, err = GetRemoteDetails(coreutils.ReleasesRemoteEnv)
if remoteRepo != "" && err == nil {
remoteRepo = getFullExtractorsPathInArtifactory(remoteRepo, coreutils.ReleasesRemoteEnv, downloadPath)
}
return
}
func getExtractorsRemoteDetailsFromLegacyEnv(downloadPath string) (server *config.ServerDetails, remoteRepo string, err error) {
server, remoteRepo, err = GetRemoteDetails(coreutils.DeprecatedExtractorsRemoteEnv)
if remoteRepo != "" && err == nil {
log.Warn(fmt.Sprintf("You are using the deprecated %q environment variable. Use %q instead.\nRead more about it at %s",
coreutils.DeprecatedExtractorsRemoteEnv, coreutils.ReleasesRemoteEnv, jarsDocumentation))
remoteRepo = getFullExtractorsPathInArtifactory(remoteRepo, coreutils.DeprecatedExtractorsRemoteEnv, downloadPath)
}
return
}
// GetRemoteDetails function retrieves the server details and downloads path for the build-info extractor file.
// serverAndRepo - the server id and the remote repository that proxies releases.jfrog.io, in form of '<ServerID>/<RemoteRepo>'.
// downloadPath - specifies the path in the remote repository from which the extractors will be downloaded.
// remoteEnv - the relevant environment variable that was used: releasesRemoteEnv/ExtractorsRemoteEnv.
// The function returns the server that matches the given server ID, the complete path of the build-info extractor concatenated with the specified remote repository, and an error if occurred.
func GetRemoteDetails(remoteEnv string) (server *config.ServerDetails, repoName string, err error) {
serverID, repoName, err := coreutils.GetServerIdAndRepo(remoteEnv)
if err != nil {
return
}
if serverID == "" && repoName == "" {
// Remote details weren't configured. Assuming that https://releases.jfrog.io should be used.
return
}
server, err = config.GetSpecificConfig(serverID, false, true)
return
}
func getFullExtractorsPathInArtifactory(repoName, remoteEnv, downloadPath string) string {
if remoteEnv == coreutils.ReleasesRemoteEnv {
return path.Join(repoName, "artifactory", "oss-release-local", downloadPath)
}
return path.Join(repoName, downloadPath)
}
// Downloads the requested resource.
//
// artDetails: The artifactory server details to download the resource from.
// downloadPath: Artifactory download path.
// targetPath: The local download path (without the file name).
func DownloadDependency(artDetails *config.ServerDetails, downloadPath, targetPath string, shouldExplode bool) (err error) {
downloadUrl := artDetails.ArtifactoryUrl + downloadPath
log.Info("Downloading JFrog's Dependency from", downloadUrl)
filename, localDir := fileutils.GetFileAndDirFromPath(targetPath)
tempDirPath, err := fileutils.CreateTempDir()
if err != nil {
return err
}
defer func() {
err = errors.Join(err, fileutils.RemoveTempDir(tempDirPath))
}()
// Get the expected check-sum before downloading
client, httpClientDetails, err := CreateHttpClient(artDetails)
if err != nil {
return err
}
expectedSha1 := ""
remoteFileDetails, _, err := client.GetRemoteFileDetails(downloadUrl, &httpClientDetails)
if err == nil {
expectedSha1 = remoteFileDetails.Checksum.Sha1
} else {
log.Warn(fmt.Sprintf("Failed to get remote file details.\n Got: %s", err))
}
// Download the file
downloadFileDetails := &httpclient.DownloadFileDetails{
FileName: filename,
DownloadPath: downloadUrl,
LocalPath: tempDirPath,
LocalFileName: filename,
ExpectedSha1: expectedSha1,
}
client, httpClientDetails, err = CreateHttpClient(artDetails)
if err != nil {
return err
}
resp, err := client.DownloadFile(downloadFileDetails, "", &httpClientDetails, shouldExplode, false)
if err != nil {
err = errorutils.CheckErrorf("received error while attempting to download '%s': %s"+downloadUrl, err.Error())
}
if err = errorutils.CheckResponseStatus(resp, http.StatusOK); err != nil {
return err
}
err = coreutils.SetPermissionsRecursively(tempDirPath, 0755)
if err != nil {
return err
}
return biutils.CopyDir(tempDirPath, localDir, true, nil)
}
func CreateHttpClient(artDetails *config.ServerDetails) (rtHttpClient *jfroghttpclient.JfrogHttpClient, httpClientDetails httputils.HttpClientDetails, err error) {
auth, err := artDetails.CreateArtAuthConfig()
if err != nil {
return
}
certsPath, err := coreutils.GetJfrogCertsDir()
if err != nil {
return
}
httpClientDetails = auth.CreateHttpClientDetails()
rtHttpClient, err = jfroghttpclient.JfrogClientBuilder().
SetCertificatesPath(certsPath).
SetInsecureTls(artDetails.InsecureTls).
SetClientCertPath(auth.GetClientCertPath()).
SetClientCertKeyPath(auth.GetClientCertKeyPath()).
AppendPreRequestInterceptor(auth.RunPreRequestFunctions).
Build()
return
}