mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[maven] [IDEA-101997] replacing classpath in junit tests to filtered jar
GitOrigin-RevId: da2e645e39f5083f3f25a0351699f5798cfb81d8
This commit is contained in:
committed by
intellij-monorepo-bot
parent
38679ee435
commit
ad6a65873a
@@ -30,4 +30,7 @@ public class MavenFilteredJarConfiguration {
|
||||
|
||||
@Tag("jarOutput")
|
||||
public @NotNull String jarOutput;
|
||||
|
||||
@Tag("name")
|
||||
public @NotNull String name;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,10 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.CompilerModuleExtension;
|
||||
import com.intellij.openapi.util.PropertiesUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -23,7 +26,9 @@ import org.jetbrains.idea.maven.project.MavenProject;
|
||||
import org.jetbrains.idea.maven.project.MavenProjectSettings;
|
||||
import org.jetbrains.idea.maven.project.MavenProjectsManager;
|
||||
import org.jetbrains.idea.maven.project.MavenTestRunningSettings;
|
||||
import org.jetbrains.idea.maven.utils.MavenFilteredJarUtils;
|
||||
import org.jetbrains.idea.maven.utils.MavenJDOMUtil;
|
||||
import org.jetbrains.jps.maven.model.impl.MavenFilteredJarConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -54,15 +59,71 @@ public final class MavenJUnitPatcher extends JUnitPatcher {
|
||||
public void patchJavaParameters(@Nullable Module module, JavaParameters javaParameters) {
|
||||
if (module == null) return;
|
||||
|
||||
MavenProject mavenProject = MavenProjectsManager.getInstance(module.getProject()).findProject(module);
|
||||
MavenProjectsManager projectsManager = MavenProjectsManager.getInstance(module.getProject());
|
||||
MavenProject mavenProject = projectsManager.findProject(module);
|
||||
if (mavenProject == null) return;
|
||||
|
||||
UnaryOperator<String> runtimeProperties = getDynamicConfigurationProperties(module, mavenProject, javaParameters);
|
||||
|
||||
configureFromPlugin(module, javaParameters, mavenProject, runtimeProperties, "maven-surefire-plugin", "surefire");
|
||||
configureFromPlugin(module, javaParameters, mavenProject, runtimeProperties, "maven-failsafe-plugin", "failsafe");
|
||||
replaceFilteredJarDirectories(projectsManager, module, javaParameters, mavenProject);
|
||||
}
|
||||
|
||||
private static void replaceFilteredJarDirectories(MavenProjectsManager projectsManager,
|
||||
@NotNull Module module,
|
||||
JavaParameters parameters,
|
||||
MavenProject project) {
|
||||
if (!Registry.is("maven.build.additional.jars")) return;
|
||||
//todo: We do dependency traversing every time, we need another structure in project tree for this to retrieve this data in a fast way
|
||||
Set<MavenArtifact> visited = new HashSet<>();
|
||||
ArrayDeque<MavenArtifact> queue = new ArrayDeque<>(project.getDependencies());
|
||||
List<MavenFilteredJarConfiguration> toReplace = new ArrayList<>();
|
||||
while (!queue.isEmpty()) {
|
||||
var dependency = queue.poll();
|
||||
var depProject = projectsManager.findProject(dependency);
|
||||
if (depProject == null) continue;
|
||||
if (!visited.add(dependency)) continue;
|
||||
MavenFilteredJarConfiguration jarConfiguration =
|
||||
findFilteredJarConfig(projectsManager, depProject, dependency.getClassifier());
|
||||
if (jarConfiguration != null) {
|
||||
LOG.debug(
|
||||
"found additional jar configuration for " + dependency + ", classpath will be replaced in tests for module " + module.getName());
|
||||
toReplace.add(jarConfiguration);
|
||||
}
|
||||
queue.addAll(depProject.getDependencies());
|
||||
}
|
||||
|
||||
if (toReplace.isEmpty()) return;
|
||||
//do not expect a lot of MavenFilteredJarConfiguration here, O(n^2) should be fine
|
||||
String[] paths = ArrayUtil.toStringArray(parameters.getClassPath().getPathList());
|
||||
boolean replaced = false;
|
||||
for (int i = 0; i < paths.length; i++) {
|
||||
String path = paths[i];
|
||||
MavenFilteredJarConfiguration config = ContainerUtil.find(toReplace, c -> FileUtil.pathsEqual(path, c.originalOutput));
|
||||
if (config != null) {
|
||||
paths[i] = config.jarOutput;
|
||||
replaced = true;
|
||||
}
|
||||
}
|
||||
if (!replaced) {
|
||||
LOG.warn(
|
||||
"expected to replace " + toReplace.size() + " dependencies in running module " + module.getName() + ", but replaced 0");
|
||||
}
|
||||
else {
|
||||
parameters.getClassPath().clear();
|
||||
parameters.getClassPath().addAll(Arrays.asList(paths));
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable MavenFilteredJarConfiguration findFilteredJarConfig(MavenProjectsManager projectsManager,
|
||||
MavenProject mavenProject, String classifier) {
|
||||
List<@NotNull MavenFilteredJarConfiguration> configurations =
|
||||
MavenFilteredJarUtils.getAllFilteredConfigurations(projectsManager, mavenProject);
|
||||
return ContainerUtil.find(configurations, c -> StringUtil.equals(c.classifier, classifier));
|
||||
}
|
||||
|
||||
|
||||
private static void configureFromPlugin(@NotNull Module module,
|
||||
JavaParameters javaParameters,
|
||||
MavenProject mavenProject,
|
||||
@@ -155,7 +216,7 @@ public final class MavenJUnitPatcher extends JUnitPatcher {
|
||||
MavenProjectsManager mavenProjectsManager = MavenProjectsManager.getInstance(module.getProject());
|
||||
if (scopeExclude != null || !excludes.isEmpty()) {
|
||||
for (MavenArtifact dependency : mavenProject.getDependencies()) {
|
||||
if (scopeExclude!=null && SCOPE_FILTER.getOrDefault(scopeExclude, Collections.emptyList()).contains(dependency.getScope()) ||
|
||||
if (scopeExclude != null && SCOPE_FILTER.getOrDefault(scopeExclude, Collections.emptyList()).contains(dependency.getScope()) ||
|
||||
excludes.contains(dependency.getGroupId() + ":" + dependency.getArtifactId())) {
|
||||
File file = dependency.getFile();
|
||||
javaParameters.getClassPath().remove(file.getAbsolutePath());
|
||||
@@ -281,7 +342,7 @@ public final class MavenJUnitPatcher extends JUnitPatcher {
|
||||
while (matcher.find()) {
|
||||
String finding = matcher.group();
|
||||
final String propertyValue = vmParameters.getPropertyValue(finding.substring(2, finding.length() - 1));
|
||||
if(propertyValue == null) continue;
|
||||
if (propertyValue == null) continue;
|
||||
toReplace.put(finding, propertyValue);
|
||||
}
|
||||
for (Map.Entry<String, String> entry : toReplace.entrySet()) {
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.maven.project.compilation
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.roots.ProjectFileIndex
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.util.text.nullize
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.idea.maven.project.MavenProject
|
||||
import org.jetbrains.idea.maven.project.MavenProjectsManager
|
||||
import org.jetbrains.idea.maven.server.RemotePathTransformerFactory
|
||||
import org.jetbrains.idea.maven.utils.MavenJDOMUtil.findChildrenValuesByPath
|
||||
import org.jetbrains.jps.maven.model.impl.MavenFilteredJarConfiguration
|
||||
import org.jetbrains.idea.maven.utils.MavenFilteredJarUtils
|
||||
import org.jetbrains.jps.maven.model.impl.MavenProjectConfiguration
|
||||
|
||||
@ApiStatus.Internal
|
||||
@@ -27,72 +23,8 @@ class FilteredJarConfigGenerator(
|
||||
return
|
||||
}
|
||||
if ("pom".equals(mavenProject.packaging)) return;
|
||||
|
||||
GOALS.forEach { g, _ ->
|
||||
mavenProject.getPluginGoalConfiguration("org.apache.maven.plugins", "maven-jar-plugin", g)?.let {
|
||||
addConfiguration(g, it)
|
||||
}
|
||||
MavenFilteredJarUtils.getAllFilteredConfigurations(mavenProjectsManager, mavenProject).forEach { jarConfig ->
|
||||
config.jarsConfiguration[jarConfig.name] = jarConfig
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun addConfiguration(goal: String, element: Element) {
|
||||
val includes = findChildrenValuesByPath(element, "includes", "include").toMutableList()
|
||||
val excludes = findChildrenValuesByPath(element, "excludes", "exclude").toMutableList()
|
||||
val classifier = element.getChildTextTrim("classifier") ?: GOALS[goal] ?: ""
|
||||
val excludeDefaults: Boolean
|
||||
if ("false".equals(element.getChildTextTrim("addDefaultExcludes"), true)) {
|
||||
excludeDefaults = false
|
||||
}
|
||||
else {
|
||||
excludeDefaults = true
|
||||
}
|
||||
|
||||
if (excludeDefaults) {
|
||||
DEFAULTEXCLUDES.forEach { _, v -> v.forEach(excludes::add) }
|
||||
}
|
||||
doAddConfiguration(goal == "test-jar", classifier, excludes, includes)
|
||||
|
||||
}
|
||||
|
||||
private fun doAddConfiguration(tests: Boolean, classifier: String, excludes: MutableList<String>, includes: MutableList<String>) {
|
||||
val module = mavenProjectsManager.findModule(mavenProject) ?: return
|
||||
val configuration = MavenFilteredJarConfiguration()
|
||||
|
||||
configuration.classifier = classifier
|
||||
configuration.excludes = excludes.toSet()
|
||||
configuration.includes = includes.toSet()
|
||||
configuration.moduleName = module.name
|
||||
val name = mavenProject.mavenId.toString() + (classifier.nullize(true)?.map { "-$it" } ?: "")
|
||||
configuration.isTest = tests
|
||||
configuration.originalOutput = if (tests) mavenProject.testOutputDirectory else mavenProject.outputDirectory;
|
||||
configuration.jarOutput = configuration.originalOutput + "-jar-" + classifier
|
||||
config.jarsConfiguration[name] = configuration
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(FilteredJarConfigGenerator::class.java)
|
||||
private val GOALS = mapOf("jar" to "", "test-jar" to "tests")
|
||||
|
||||
//https://codehaus-plexus.github.io/plexus-utils/apidocs/org/codehaus/plexus/util/AbstractScanner.html#DEFAULTEXCLUDES
|
||||
private val DEFAULTEXCLUDES = mapOf<String, Array<String>>(
|
||||
"Misc" to arrayOf(" **/*~", "**/#*#", "**/.#*", "**/%*%", "*/._*"),
|
||||
"CVS" to arrayOf("*/CVS", "**/CVS/**", "**/.cvsignore"),
|
||||
"RCS" to arrayOf("**/RCS", "**/RCS/**"),
|
||||
"SCCS" to arrayOf("**/SCCS", "**/SCCS/**"),
|
||||
"VSSercer" to arrayOf(" **/vssver.scc"),
|
||||
"MKS" to arrayOf("**/project.pj"),
|
||||
"SVN" to arrayOf("**/.svn", "**/.svn/**"),
|
||||
"GNU" to arrayOf("**/.arch-ids", "**/.arch-ids/**"),
|
||||
"Bazaar" to arrayOf("**/.bzr", "**/.bzr/**"),
|
||||
"SurroundSCM" to arrayOf("**/.MySCMServerInfo"),
|
||||
"Mac" to arrayOf("**/.DS_Store"),
|
||||
"Serena Dimension" to arrayOf("**/.metadata", "**/.metadata/**"),
|
||||
"Mercurial" to arrayOf("**/.hg", "**/.hg/**"),
|
||||
"Git" to arrayOf("**/.git", "**/.git/**", "**/.gitignore"),
|
||||
"Bitkeeper" to arrayOf("**/BitKeeper", "**/BitKeeper/**", "**/ChangeSet", "**/ChangeSet/**"),
|
||||
"Darcs" to arrayOf("**/_darcs", "**/_darcs/**", "**/.darcsrepo", "**/.darcsrepo/****/-darcs-backup*", "**/.darcs-temp-mail"),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.maven.utils
|
||||
|
||||
import com.intellij.util.text.nullize
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.idea.maven.project.MavenProject
|
||||
import org.jetbrains.idea.maven.project.MavenProjectsManager
|
||||
import org.jetbrains.idea.maven.utils.MavenJDOMUtil.findChildrenValuesByPath
|
||||
import org.jetbrains.jps.maven.model.impl.MavenFilteredJarConfiguration
|
||||
|
||||
class MavenFilteredJarUtils {
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getAllFilteredConfigurations(mavenProjectsManager: MavenProjectsManager, mavenProject: MavenProject): List<MavenFilteredJarConfiguration> {
|
||||
if ("pom".equals(mavenProject.packaging)) return emptyList()
|
||||
|
||||
val result = ArrayList<MavenFilteredJarConfiguration>()
|
||||
for (e in GOALS) {
|
||||
val element = mavenProject.getPluginGoalConfiguration("org.apache.maven.plugins", "maven-jar-plugin", e.key) ?: continue
|
||||
loadConfiguration(mavenProjectsManager, mavenProject, element, e.key)?.also {
|
||||
result.add(it)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun loadConfiguration(mavenProjectsManager: MavenProjectsManager, mavenProject: MavenProject, element: Element, goal: String): MavenFilteredJarConfiguration? {
|
||||
val includes = findChildrenValuesByPath(element, "includes", "include").toMutableList()
|
||||
val excludes = findChildrenValuesByPath(element, "excludes", "exclude").toMutableList()
|
||||
if (excludes.isEmpty() && includes.isEmpty()) return null //no configurations if jar is not filtered
|
||||
val classifier = element.getChildTextTrim("classifier") ?: GOALS[goal] ?: ""
|
||||
val excludeDefaults: Boolean
|
||||
if ("false".equals(element.getChildTextTrim("addDefaultExcludes"), true)) {
|
||||
excludeDefaults = false
|
||||
}
|
||||
else {
|
||||
excludeDefaults = true
|
||||
}
|
||||
|
||||
if (excludeDefaults) {
|
||||
DEFAULTEXCLUDES.forEach { _, v -> v.forEach(excludes::add) }
|
||||
}
|
||||
|
||||
val module = mavenProjectsManager.findModule(mavenProject) ?: return null
|
||||
val configuration = MavenFilteredJarConfiguration()
|
||||
val tests = goal == "test-jar"
|
||||
|
||||
configuration.classifier = classifier
|
||||
configuration.excludes = excludes.toSet()
|
||||
configuration.includes = includes.toSet()
|
||||
configuration.moduleName = module.name
|
||||
configuration.isTest = tests
|
||||
configuration.originalOutput = if (tests) mavenProject.testOutputDirectory else mavenProject.outputDirectory;
|
||||
configuration.jarOutput = configuration.originalOutput + "-jar-" + classifier
|
||||
configuration.name = mavenProject.mavenId.toString() + (classifier.nullize(true)?.map { "-$it" } ?: "")
|
||||
return configuration
|
||||
}
|
||||
|
||||
private val GOALS = mapOf("jar" to "", "test-jar" to "tests")
|
||||
|
||||
//https://codehaus-plexus.github.io/plexus-utils/apidocs/org/codehaus/plexus/util/AbstractScanner.html#DEFAULTEXCLUDES
|
||||
private val DEFAULTEXCLUDES = mapOf<String, Array<String>>(
|
||||
"Misc" to arrayOf(" **/*~", "**/#*#", "**/.#*", "**/%*%", "*/._*"),
|
||||
"CVS" to arrayOf("*/CVS", "**/CVS/**", "**/.cvsignore"),
|
||||
"RCS" to arrayOf("**/RCS", "**/RCS/**"),
|
||||
"SCCS" to arrayOf("**/SCCS", "**/SCCS/**"),
|
||||
"VSSercer" to arrayOf(" **/vssver.scc"),
|
||||
"MKS" to arrayOf("**/project.pj"),
|
||||
"SVN" to arrayOf("**/.svn", "**/.svn/**"),
|
||||
"GNU" to arrayOf("**/.arch-ids", "**/.arch-ids/**"),
|
||||
"Bazaar" to arrayOf("**/.bzr", "**/.bzr/**"),
|
||||
"SurroundSCM" to arrayOf("**/.MySCMServerInfo"),
|
||||
"Mac" to arrayOf("**/.DS_Store"),
|
||||
"Serena Dimension" to arrayOf("**/.metadata", "**/.metadata/**"),
|
||||
"Mercurial" to arrayOf("**/.hg", "**/.hg/**"),
|
||||
"Git" to arrayOf("**/.git", "**/.git/**", "**/.gitignore"),
|
||||
"Bitkeeper" to arrayOf("**/BitKeeper", "**/BitKeeper/**", "**/ChangeSet", "**/ChangeSet/**"),
|
||||
"Darcs" to arrayOf("**/_darcs", "**/_darcs/**", "**/.darcsrepo", "**/.darcsrepo/****/-darcs-backup*", "**/.darcs-temp-mail"),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user