/
env.go
187 lines (174 loc) · 6.02 KB
/
env.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
* Copyright 2021-2023 JetBrains s.r.o.
*
* 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
*
* https://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 core
import (
"fmt"
cienvironment "github.com/cucumber/ci-environment/go"
log "github.com/sirupsen/logrus"
"net/url"
"os"
"runtime"
"strings"
)
const (
qodanaEnv = "QODANA_ENV"
QodanaToken = "QODANA_TOKEN"
QodanaLicenseOnlyToken = "QODANA_LICENSE_ONLY_TOKEN"
qodanaJobUrl = "QODANA_JOB_URL"
qodanaRemoteUrl = "QODANA_REMOTE_URL"
qodanaBranch = "QODANA_BRANCH"
qodanaRevision = "QODANA_REVISION"
qodanaCliContainerName = "QODANA_CLI_CONTAINER_NAME"
qodanaCliContainerKeep = "QODANA_CLI_CONTAINER_KEEP"
qodanaCliUsePodman = "QODANA_CLI_USE_PODMAN"
qodanaDockerEnv = "QODANA_DOCKER"
QodanaConfEnv = "QODANA_CONF"
QodanaToolEnv = "QODANA_TOOL"
QodanaDistEnv = "QODANA_DIST"
qodanaCorettoSdk = "QODANA_CORETTO_SDK"
androidSdkRoot = "ANDROID_SDK_ROOT"
QodanaLicenseEndpoint = "LICENSE_ENDPOINT"
QodanaLicense = "QODANA_LICENSE"
QodanaProjectIdHash = "QODANA_PROJECT_ID_HASH"
QodanaTreatAsRelease = "QODANA_TREAT_AS_RELEASE"
qodanaClearKeyring = "QODANA_CLEAR_KEYRING"
qodanaNugetUrl = "QODANA_NUGET_URL"
qodanaNugetUser = "QODANA_NUGET_USER"
qodanaNugetPassword = "QODANA_NUGET_PASSWORD"
qodanaNugetName = "QODANA_NUGET_NAME"
qodanaRepoUrl = "QODANA_REPO_URL"
)
// ExtractQodanaEnvironment extracts Qodana environment variables from the current environment.
func ExtractQodanaEnvironment(setEnvironmentFunc func(string, string)) {
ci := cienvironment.DetectCIEnvironment()
qEnv := "cli"
if ci != nil {
qEnv = strings.ReplaceAll(strings.ToLower(ci.Name), " ", "-")
setEnvironmentFunc(qodanaJobUrl, validateJobUrl(ci.URL, qEnv))
if ci.Git != nil {
setEnvironmentFunc(qodanaRemoteUrl, validateRemoteUrl(ci.Git.Remote, qEnv))
setEnvironmentFunc(qodanaBranch, validateBranch(ci.Git.Branch, qEnv))
setEnvironmentFunc(qodanaRevision, ci.Git.Revision)
setEnvironmentFunc(qodanaRepoUrl, getRepositoryHttpUrl(qEnv, ci.Git.Remote))
}
setEnvironmentFunc(qodanaNugetUrl, os.Getenv(qodanaNugetUrl))
setEnvironmentFunc(qodanaNugetUser, os.Getenv(qodanaNugetUser))
setEnvironmentFunc(qodanaNugetPassword, os.Getenv(qodanaNugetPassword))
setEnvironmentFunc(qodanaNugetName, os.Getenv(qodanaNugetName))
} else if space := os.Getenv("JB_SPACE_API_URL"); space != "" {
qEnv = "space"
setEnvironmentFunc(qodanaJobUrl, os.Getenv("JB_SPACE_EXECUTION_URL"))
setEnvironmentFunc(qodanaRemoteUrl, getSpaceRemoteUrl())
setEnvironmentFunc(qodanaBranch, os.Getenv("JB_SPACE_GIT_BRANCH"))
setEnvironmentFunc(qodanaRevision, os.Getenv("JB_SPACE_GIT_REVISION"))
setEnvironmentFunc(qodanaRepoUrl, getRepositoryHttpUrl(qEnv, ""))
}
setEnvironmentFunc(qodanaEnv, fmt.Sprintf("%s:%s", qEnv, Version))
}
func validateRemoteUrl(remote string, qEnv string) string {
if strings.HasPrefix(qEnv, "space") {
return getSpaceRemoteUrl()
}
_, err := url.ParseRequestURI(remote)
if remote == "" || err != nil {
log.Warnf("Unable to parse git remote URL %s, set %s env variable for proper qodana.cloud reporting", remote, qodanaRemoteUrl)
return ""
}
return remote
}
func getRepositoryHttpUrl(qEnv string, remoteUrl string) string {
switch qEnv {
case "gitlab":
return os.Getenv("CI_PROJECT_URL") // gitlab exposes this directly, don't need to mess with the url
case "space":
return strings.Join([]string{
"https://",
os.Getenv("JB_SPACE_API_URL"),
"/p/",
os.Getenv("JB_SPACE_PROJECT_KEY"),
"/repositories/",
os.Getenv("JB_SPACE_GIT_REPOSITORY_NAME"),
}, "")
default:
remoteUrl = strings.TrimSuffix(remoteUrl, ".git")
}
parsed, err := url.ParseRequestURI(remoteUrl)
if remoteUrl == "" || err != nil || !strings.HasPrefix(parsed.Scheme, "http") {
log.Warnf("Unable to parse http(s) remote URL from %s, set %s env variable for proper qodana.cloud reporting", remoteUrl, qodanaRepoUrl)
return ""
}
parsed.User = nil
return parsed.String()
}
func validateBranch(branch string, env string) string {
if branch == "" {
if env == "github-actions" {
branch = os.Getenv("GITHUB_REF")
if strings.Contains(branch, "/pull/") {
branch = os.Getenv("GITHUB_HEAD_REF")
}
} else if env == "azure-pipelines" {
branch = os.Getenv("BUILD_SOURCEBRANCHNAME")
} else if env == "jenkins" {
branch = os.Getenv("GIT_BRANCH")
}
}
if branch == "" {
log.Warnf("Unable to parse git branch, set %s env variable for proper qodana.cloud reporting", qodanaBranch)
return ""
}
return branch
}
func validateJobUrl(ciUrl string, qEnv string) string {
if strings.HasPrefix(qEnv, "azure") { // temporary workaround for Azure Pipelines
return getAzureJobUrl()
}
_, err := url.ParseRequestURI(ciUrl)
if err != nil {
return ""
}
return ciUrl
}
// bootstrap takes the given command (from CLI or qodana.yaml) and runs it.
func bootstrap(command string, project string) {
if command != "" {
log.Printf("Running %s...", command)
var executor string
var flag string
switch runtime.GOOS {
case "windows":
executor = "cmd"
flag = "/c"
default:
executor = "sh"
flag = "-c"
}
if res := RunCmd(project, executor, flag, command); res > 0 {
log.Printf("Provided bootstrap command finished with error: %d. Exiting...", res)
os.Exit(res)
}
}
}
func setEnv(key string, value string) {
log.Debugf("Setting %s=%s", key, value)
if os.Getenv(key) == "" && value != "" {
err := os.Setenv(key, value)
if err != nil {
return
}
log.Debugf("Set %s=%s", key, value)
}
}