Skip to content

Commit 5b64ead

Browse files
committed
Rough draft of removing jars from the plugin and downloading the required jars at runtime
1 parent 8c610f8 commit 5b64ead

File tree

10 files changed

+68
-302
lines changed

10 files changed

+68
-302
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ tasks {
5454
// }
5555

5656
withType<VerifyPluginTask> {
57-
dependsOn(copyClassesToSandbox, copyCheckstyleArtifactsToSandbox)
57+
dependsOn(copyClassesToSandbox)
5858
}
5959

6060
withType<Test> {

buildSrc/src/main/java/org/infernus/idea/checkstyle/build/CheckstyleVersions.java

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@ public class CheckstyleVersions {
2121
private static final String PROP_FILE = "src/main/resources/checkstyle-idea.properties";
2222

2323
private static final String PROP_VERSIONS_SUPPORTED = "checkstyle.versions.supported";
24-
private static final String PROP_DEPENDENCY_MAP = "checkstyle.dependencies.map";
2524
private static final String PROP_NAME_BASEVERSION = "baseVersion";
2625

2726
private final File propertyFile;
2827

2928
private final SortedSet<String> versions;
30-
private final Map<String, String> dependencyMappings;
3129

3230
private final String baseVersion;
3331

@@ -37,7 +35,6 @@ public CheckstyleVersions(final Project project) {
3735
final Properties properties = readProperties();
3836
versions = buildVersionSet(properties);
3937
baseVersion = readBaseVersion(properties);
40-
dependencyMappings = readDependencyMap(properties);
4138
}
4239

4340
private SortedSet<String> buildVersionSet(final Properties properties) {
@@ -89,22 +86,6 @@ private String readBaseVersion(final Properties properties) {
8986
return baseVersionValue;
9087
}
9188

92-
private Map<String, String> readDependencyMap(final Properties properties) {
93-
final String propertyValue = properties.getProperty(PROP_DEPENDENCY_MAP);
94-
if (propertyValue == null || propertyValue.trim().isEmpty()) {
95-
return Collections.emptyMap();
96-
}
97-
98-
final Map<String, String> mappings = new HashMap<>();
99-
for (final String mapping : propertyValue.trim().split("\\s*,\\s*")) {
100-
if (!mapping.isEmpty()) {
101-
final String[] oldDependencyToNewDependency = parseKeyValueMapping(mapping);
102-
mappings.put(oldDependencyToNewDependency[0], oldDependencyToNewDependency[1]);
103-
}
104-
}
105-
return Collections.unmodifiableMap(mappings);
106-
}
107-
10889
public File getPropertyFile() {
10990
return propertyFile;
11091
}
@@ -130,17 +111,4 @@ public static Dependency createCheckstyleDependency(final Project project, final
130111
csDep.exclude(ex);
131112
return csDep;
132113
}
133-
134-
private String[] parseKeyValueMapping(final String mapping) {
135-
final String[] kv = mapping.split("\\s*->\\s*");
136-
if (kv.length != 2) {
137-
throw new GradleException("Internal error: Property '" + CheckstyleVersions.PROP_DEPENDENCY_MAP
138-
+ "' contains invalid mapping '" + mapping + "'");
139-
}
140-
return kv;
141-
}
142-
143-
public Map<String, String> getDependencyMappings() {
144-
return dependencyMappings;
145-
}
146114
}

buildSrc/src/main/java/org/infernus/idea/checkstyle/build/GatherCheckstyleArtifactsTask.java

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,29 +61,6 @@ public GatherCheckstyleArtifactsTask() {
6161
public void runTask() {
6262
final Set<File> bundledFiles = new TreeSet<>();
6363
final Properties classPaths = new SortedProperties();
64-
final Set<String> availableFileNames = new HashSet<>();
65-
66-
for (final String csVersion : csVersions.getVersions()) {
67-
Set<File> dependencies = rawVersionsToDependencies.get(csVersion);
68-
availableFileNames.addAll(dependencies.stream().map(File::getName).collect(toSet()));
69-
}
70-
71-
final Map<String, String> dependencyMappings = csVersions.getDependencyMappings();
72-
for (final String csVersion : csVersions.getVersions()) {
73-
Set<String> processedDependencies = rawVersionsToDependencies.get(csVersion).stream()
74-
.map(dependencyFile -> {
75-
if (csVersions.getDependencyMappings().containsKey(dependencyFile.getName())
76-
&& availableFileNames.contains(dependencyMappings.get(dependencyFile.getName()))) {
77-
return dependencyMappings.get(dependencyFile.getName());
78-
} else {
79-
bundledFiles.add(dependencyFile);
80-
return dependencyFile.getName();
81-
}
82-
})
83-
.collect(toSet());
84-
85-
classPaths.setProperty(csVersion, convertToClassPath(processedDependencies));
86-
}
8764

8865
copyFiles(bundledFiles);
8966
createClassPathsFile(classPaths);

buildSrc/src/main/java/org/infernus/idea/checkstyle/build/GradlePluginMain.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,6 @@ private void createCheckstyleArtifactTasks(final Project project) {
110110
mainSourceSet.getResources().srcDir(task.getClassPathsInfoFile().getParentFile());
111111
});
112112

113-
createCopyCheckstyleArtifactsToSandboxTask(project, false);
114-
createCopyCheckstyleArtifactsToSandboxTask(project, true);
115-
116113
createCopyClassesToSandboxTask(project, false);
117114
createCopyClassesToSandboxTask(project, true);
118115
}
@@ -174,10 +171,8 @@ private void createCopyClassesToSandboxTask(final Project project, final boolean
174171
tasks.getByName(JavaPlugin.TEST_TASK_NAME).dependsOn(copyTask);
175172
tasks.getByName(CsaccessTestTask.NAME).dependsOn(copyTask);
176173
forEachXTest(tasks, xTask -> xTask.dependsOn(copyTask));
177-
copyTask.mustRunAfter(tasks.getByName("copyCheckstyleArtifactsToTestSandbox"));
178174
} else {
179175
tasks.getByName("buildSearchableOptions").dependsOn(copyTask);
180-
copyTask.mustRunAfter(tasks.getByName("copyCheckstyleArtifactsToSandbox"));
181176
}
182177

183178
copyTask.from(csaccessSourceSet.getOutput());
@@ -201,13 +196,10 @@ private void wireIntellijPluginTasks(final Project project) {
201196
final TaskContainer tasks = project.getTasks();
202197
tasks.all((Task task) -> {
203198
if ("buildPlugin".equals(task.getName()) || "runIdea".equals(task.getName()) || "runIde".equals(task.getName())) {
204-
task.dependsOn(tasks.getByName("copyCheckstyleArtifactsToSandbox"));
205199
task.dependsOn(tasks.getByName("copyClassesToSandbox"));
206200
} else if ("prepareSandbox".equals(task.getName())) {
207-
tasks.getByName("copyCheckstyleArtifactsToSandbox").dependsOn(task);
208201
tasks.getByName("copyClassesToSandbox").dependsOn(task);
209202
} else if ("prepareTestsSandbox".equals(task.getName())) {
210-
tasks.getByName("copyCheckstyleArtifactsToTestSandbox").dependsOn(task);
211203
tasks.getByName("copyClassesToTestSandbox").dependsOn(task);
212204
}
213205
});

src/main/java/org/infernus/idea/checkstyle/CheckstyleClassLoaderContainer.java

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.intellij.openapi.application.PathManager;
44
import com.intellij.openapi.project.Project;
55
import com.intellij.util.lang.UrlClassLoader;
6+
import java.nio.file.Path;
67
import org.infernus.idea.checkstyle.csapi.CheckstyleActions;
78
import org.infernus.idea.checkstyle.exception.CheckStylePluginException;
89
import org.infernus.idea.checkstyle.util.ChildFirstURLClassLoader;
@@ -21,7 +22,6 @@
2122
import java.util.regex.Pattern;
2223

2324
import static org.infernus.idea.checkstyle.CheckStyleBundle.message;
24-
import static org.infernus.idea.checkstyle.util.Strings.isBlank;
2525

2626

2727
/**
@@ -60,17 +60,12 @@ public class CheckstyleClassLoaderContainer {
6060

6161
public CheckstyleClassLoaderContainer(@NotNull final Project project,
6262
@NotNull final CheckstyleProjectService checkstyleProjectService,
63-
@NotNull final String checkstyleVersion,
63+
@NotNull final Path jarPath,
6464
@Nullable final List<URL> thirdPartyClassPath) {
6565
this.project = project;
6666
this.checkstyleProjectService = checkstyleProjectService;
6767

68-
final Properties classPathInfos = loadClassPathInfos();
69-
final String cpProp = classPathInfos.getProperty(checkstyleVersion);
70-
if (isBlank(cpProp)) {
71-
throw new CheckStylePluginException("Unsupported Checkstyle version: " + checkstyleVersion);
72-
}
73-
classLoader = buildClassLoader(cpProp, emptyListIfNull(thirdPartyClassPath));
68+
classLoader = buildClassLoader(jarPath, emptyListIfNull(thirdPartyClassPath));
7469
}
7570

7671
@NotNull
@@ -90,15 +85,15 @@ private static Properties loadClassPathInfos() {
9085
}
9186

9287
@NotNull
93-
private ClassLoader buildClassLoader(@NotNull final String classPathFromProps,
88+
private ClassLoader buildClassLoader(@NotNull final Path jarPath,
9489
@NotNull final List<URL> thirdPartyClasspath) {
9590
final String basePluginPath = getBasePluginPath();
9691

9792
List<URL> urls;
9893
if (basePluginPath != null) {
99-
urls = baseClasspathUrlsForPackagedPlugin(classPathFromProps, basePluginPath);
94+
urls = baseClasspathUrlsForPackagedPlugin(jarPath, basePluginPath);
10095
} else {
101-
urls = baseClasspathUrlsForIDEAUnitTests(classPathFromProps);
96+
urls = baseClasspathUrlsForIDEAUnitTests(jarPath);
10297
}
10398

10499
urls.addAll(thirdPartyClasspath);
@@ -114,19 +109,12 @@ private ClassLoader buildClassLoader(@NotNull final String classPathFromProps,
114109
return newClassLoader;
115110
}
116111

117-
private static List<URL> baseClasspathUrlsForPackagedPlugin(@NotNull final String classPathFromProps,
112+
private static List<URL> baseClasspathUrlsForPackagedPlugin(@NotNull final Path jarPath,
118113
@NotNull final String basePath) {
119114
try {
120115
final List<URL> urls = new ArrayList<>();
121116
urls.add(getClassesDirectory(basePath).toURI().toURL());
122-
123-
for (String jar : splitClassPathFromProperties(classPathFromProps)) {
124-
File jarLocation = new File(basePath, jar);
125-
if (!jarLocation.exists()) {
126-
throw new CheckStylePluginException("Cannot find packaged artefact: " + jarLocation.getAbsolutePath());
127-
}
128-
urls.add(jarLocation.toURI().toURL());
129-
}
117+
urls.add(jarPath.toUri().toURL());
130118

131119
return urls;
132120

@@ -137,7 +125,7 @@ private static List<URL> baseClasspathUrlsForPackagedPlugin(@NotNull final Strin
137125

138126
private static @NotNull File getClassesDirectory(@NotNull final String basePath) {
139127
final File basePathFile = new File(basePath);
140-
if (!new File(basePath).exists()) {
128+
if (!basePathFile.exists()) {
141129
throw new CheckStylePluginException("Cannot find plugin directory: " + basePathFile.getAbsolutePath());
142130
}
143131

@@ -149,22 +137,14 @@ private static List<URL> baseClasspathUrlsForPackagedPlugin(@NotNull final Strin
149137
return classesDirectory;
150138
}
151139

152-
private List<URL> baseClasspathUrlsForIDEAUnitTests(@NotNull final String classPathFromProps) {
140+
private List<URL> baseClasspathUrlsForIDEAUnitTests(@NotNull final Path jarPath) {
153141
try {
154142
final List<URL> urls = new ArrayList<>();
155143
final String buildPath = guessBuildPathFromClasspath();
156144
URL unitTestingClassPath = getUnitTestingClassPath(buildPath);
157145

158146
urls.add(unitTestingClassPath);
159-
160-
for (String jar : splitClassPathFromProperties(classPathFromProps)) {
161-
String testJarLocation = "tmp/gatherCheckstyleArtifacts" + jar.substring(jar.lastIndexOf('/'));
162-
File jarLocation = new File(buildPath, testJarLocation);
163-
if (!jarLocation.exists()) {
164-
throw new CheckStylePluginException("Cannot find collected artefact: " + jarLocation.getAbsolutePath());
165-
}
166-
urls.add(jarLocation.toURI().toURL());
167-
}
147+
urls.add(jarPath.toUri().toURL());
168148

169149
return urls;
170150

src/main/java/org/infernus/idea/checkstyle/CheckstyleProjectService.java

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,22 @@
22

33
import com.intellij.openapi.diagnostic.Logger;
44
import com.intellij.openapi.project.Project;
5-
import org.infernus.idea.checkstyle.config.PluginConfigurationManager;
6-
import org.infernus.idea.checkstyle.csapi.CheckstyleActions;
7-
import org.infernus.idea.checkstyle.exception.CheckStylePluginException;
8-
import org.jetbrains.annotations.NotNull;
9-
import org.jetbrains.annotations.Nullable;
10-
5+
import com.intellij.util.io.HttpRequests;
116
import java.io.File;
7+
import java.io.IOException;
128
import java.net.MalformedURLException;
139
import java.net.URL;
10+
import java.nio.file.Files;
11+
import java.nio.file.Path;
1412
import java.util.ArrayList;
1513
import java.util.List;
1614
import java.util.SortedSet;
1715
import java.util.concurrent.Callable;
18-
16+
import org.infernus.idea.checkstyle.config.PluginConfigurationManager;
17+
import org.infernus.idea.checkstyle.csapi.CheckstyleActions;
18+
import org.infernus.idea.checkstyle.exception.CheckStylePluginException;
19+
import org.jetbrains.annotations.NotNull;
20+
import org.jetbrains.annotations.Nullable;
1921

2022
/**
2123
* Makes the Checkstyle tool available to the plugin in the correct version. Registered in {@code plugin.xml}.
@@ -79,33 +81,55 @@ private String getDefaultVersion() {
7981
public void activateCheckstyleVersion(@Nullable final String requestedVersion,
8082
@Nullable final List<String> thirdPartyJars) {
8183
String checkstyleVersionToLoad = versionToLoad(requestedVersion);
82-
synchronized (project) {
84+
try {
85+
// TODO: File IO and Network IO shouldn't happen on the EDT. Need to move this work to a
86+
// background thread which will introduce the need to communicate the background
87+
// downloads to users and prevent scans while downloads are in progress.
88+
// TODO: Should be a configurable cache directory.
89+
final var cacheDirectoryPath = Path.of(System.getProperty("java.io.tmpdir"), "checkstyle-idea-cache");
90+
if (!Files.exists(cacheDirectoryPath)) {
91+
Files.createDirectory(cacheDirectoryPath);
92+
}
93+
final String artifactName = "checkstyle-" + checkstyleVersionToLoad + "-all.jar";
94+
final var jarPath = cacheDirectoryPath.resolve(artifactName);
95+
if (!Files.exists(jarPath)) {
96+
HttpRequests.request("https://github.com/checkstyle/checkstyle/releases/download/checkstyle-" + checkstyleVersionToLoad + "/" + artifactName)
97+
.forceHttps(false)
98+
.connectTimeout(10_000)
99+
.readTimeout(30_000)
100+
.saveToFile(jarPath, null);
101+
}
102+
103+
synchronized (project) {
83104
checkstyleClassLoaderContainer = null;
84105
checkstyleClassLoaderFactory = new Callable<>() {
85-
@Override
86-
public CheckstyleClassLoaderContainer call() {
87-
return new CheckstyleClassLoaderContainer(
88-
project,
89-
CheckstyleProjectService.this,
90-
checkstyleVersionToLoad,
91-
toListOfUrls(thirdPartyJars));
92-
}
93-
94-
@NotNull
95-
private List<URL> toListOfUrls(@Nullable final List<String> jarFilePaths) {
96-
List<URL> result = new ArrayList<>();
97-
if (jarFilePaths != null) {
98-
for (final String absolutePath : jarFilePaths) {
99-
try {
100-
result.add(new File(absolutePath).toURI().toURL());
101-
} catch (MalformedURLException e) {
102-
LOG.warn("Skipping malformed third party classpath entry: " + absolutePath, e);
103-
}
104-
}
106+
@Override
107+
public CheckstyleClassLoaderContainer call() {
108+
return new CheckstyleClassLoaderContainer(
109+
project,
110+
CheckstyleProjectService.this,
111+
jarPath,
112+
toListOfUrls(thirdPartyJars));
113+
}
114+
115+
@NotNull
116+
private List<URL> toListOfUrls(@Nullable final List<String> jarFilePaths) {
117+
List<URL> result = new ArrayList<>();
118+
if (jarFilePaths != null) {
119+
for (final String absolutePath : jarFilePaths) {
120+
try {
121+
result.add(new File(absolutePath).toURI().toURL());
122+
} catch (MalformedURLException e) {
123+
LOG.warn("Skipping malformed third party classpath entry: " + absolutePath, e);
105124
}
106-
return result;
125+
}
107126
}
127+
return result;
128+
}
108129
};
130+
}
131+
} catch (IOException e) {
132+
throw new RuntimeException(e);
109133
}
110134
}
111135

0 commit comments

Comments
 (0)