-
Notifications
You must be signed in to change notification settings - Fork 570
/
Copy pathGoSdkService.java
167 lines (143 loc) · 6.42 KB
/
GoSdkService.java
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
/*
* Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan
*
* 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 com.goide.sdk;
import com.goide.GoConstants;
import com.goide.GoEnvironmentUtil;
import com.intellij.execution.configurations.PathEnvironmentVariableUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PathUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.io.File;
import java.util.Set;
public abstract class GoSdkService extends SimpleModificationTracker {
public static final Logger LOG = Logger.getInstance(GoSdkService.class);
private static final Set<String> FEDORA_SUBDIRECTORIES = ContainerUtil.newHashSet("linux_amd64", "linux_386", "linux_arm");
private static String ourTestSdkVersion;
@NotNull
protected final Project myProject;
protected GoSdkService(@NotNull Project project) {
myProject = project;
}
public static GoSdkService getInstance(@NotNull Project project) {
return ServiceManager.getService(project, GoSdkService.class);
}
@Nullable
public abstract String getSdkHomePath(@Nullable Module module);
@NotNull
public static String libraryRootToSdkPath(@NotNull VirtualFile root) {
return VfsUtilCore.urlToPath(StringUtil.trimEnd(StringUtil.trimEnd(StringUtil.trimEnd(root.getUrl(), "src/pkg"), "src"), "/"));
}
@Nullable
public String getSdkVersion(@Nullable Module module) {
return ourTestSdkVersion;
}
public boolean isAppEngineSdk(@Nullable Module module) {
return isAppEngineSdkPath(getSdkHomePath(module));
}
public static boolean isAppEngineSdkPath(@Nullable String path) {
return isLooksLikeAppEngineSdkPath(path) && getGaeExecutablePath(path) != null;
}
private static boolean isLooksLikeAppEngineSdkPath(@Nullable String path) {
return path != null && path.endsWith(GoConstants.APP_ENGINE_GO_ROOT_DIRECTORY_PATH);
}
public abstract void chooseAndSetSdk(@Nullable Module module);
/**
* Use this method in order to check whether the method is appropriate for providing Go-specific code insight
*/
@Contract("null -> false")
public boolean isGoModule(@Nullable Module module) {
return module != null && !module.isDisposed();
}
@Nullable
public Configurable createSdkConfigurable() {
return null;
}
@Nullable
public String getGoExecutablePath(@Nullable Module module) {
return getGoExecutablePath(getSdkHomePath(module));
}
public static String getGoExecutablePath(@Nullable String sdkHomePath) {
if (sdkHomePath != null) {
if (isLooksLikeAppEngineSdkPath(sdkHomePath)) {
LOG.debug("Looks like GAE sdk at " + sdkHomePath);
String executablePath = getGaeExecutablePath(sdkHomePath);
if (executablePath != null) return executablePath;
}
File binDirectory = new File(sdkHomePath, "bin");
if (!binDirectory.exists() && SystemInfo.isLinux) {
LOG.debug(sdkHomePath + "/bin doesn't exist, checking linux-specific paths");
// failed to define executable path in old linux and old go
File goFromPath = PathEnvironmentVariableUtil.findInPath(GoConstants.GO_EXECUTABLE_NAME);
if (goFromPath != null && goFromPath.exists()) {
LOG.debug("Go executable found at " + goFromPath.getAbsolutePath());
return goFromPath.getAbsolutePath();
}
}
String executableName = GoEnvironmentUtil.getBinaryFileNameForPath(GoConstants.GO_EXECUTABLE_NAME);
String executable = FileUtil.join(sdkHomePath, "bin", executableName);
if (!new File(executable).exists() && SystemInfo.isLinux) {
LOG.debug(executable + " doesn't exists. Looking for binaries in fedora-specific directories");
// fedora
for (String directory : FEDORA_SUBDIRECTORIES) {
File file = new File(binDirectory, directory);
if (file.exists() && file.isDirectory()) {
LOG.debug("Go executable found at " + file.getAbsolutePath());
return FileUtil.join(file.getAbsolutePath(), executableName);
}
}
}
LOG.debug("Go executable found at " + executable);
return executable;
}
return null;
}
@Nullable
private static String getGaeExecutablePath(@NotNull String sdkHomePath) {
String goExecutablePath = PathUtil.toSystemIndependentName(sdkHomePath);
goExecutablePath = StringUtil.trimEnd(goExecutablePath, GoConstants.APP_ENGINE_GO_ROOT_DIRECTORY_PATH);
boolean gcloudInstallation = goExecutablePath.endsWith(GoConstants.GCLOUD_APP_ENGINE_DIRECTORY_PATH);
if (gcloudInstallation) {
LOG.debug("Detected gcloud GAE installation at " + goExecutablePath);
goExecutablePath = FileUtil.join(StringUtil.trimEnd(goExecutablePath, GoConstants.GCLOUD_APP_ENGINE_DIRECTORY_PATH), "bin");
}
String executablePath = FileUtil.join(goExecutablePath, GoEnvironmentUtil.getGaeExecutableFileName(gcloudInstallation));
return new File(executablePath).exists() ? executablePath : null;
}
@TestOnly
public static void setTestingSdkVersion(@Nullable String version, @NotNull Disposable disposable) {
ourTestSdkVersion = version;
Disposer.register(disposable, () -> {
//noinspection AssignmentToStaticFieldFromInstanceMethod
ourTestSdkVersion = null;
});
}
}